<?php
/**********************************************************************************
WIKINDX: Bibliographic Management system.
Copyright (C)

This program is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program;
if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

The WIKINDX Team 2007
sirfragalot@users.sourceforge.net
**********************************************************************************/
/*****
* SYSTEMCHECK class
*
* Sanity check - check all system variables etc. are present and correct and
* write some to the session.
*
*	$Header: /cvsroot/wikindx/wikindx3/core/init/SYSTEMCHECK.php,v 1.48 2007/10/26 14:42:41 sirfragalot Exp $
*
*****/
class SYSTEMCHECK
{
// Constructor
	function SYSTEMCHECK($db, $vars = FALSE)
	{
		$this->db = $db;
		$this->vars = $vars;
		include_once("core/init/CORRECTBACKSLASH.php");
		$this->correctBs = new CORRECTBACKSLASH();
		$this->pString = '';
		$this->updatedDb = FALSE;
		include_once("core/session/SESSION.php");
		$this->session = new SESSION();
		include_once("core/messages/MESSAGES.php");
		$this->message = new MESSAGES();
		include_once("core/messages/ERRORS.php");
		$this->error = new ERRORS();
		$this->checkDatabase();
		$this->populateSession();
		if($this->pString)
		{
			include_once("core/html/CLOSE.php");
			new CLOSE($this->db, $this->pString);
		}
	}
// We know we have a database as, if we've reached this stage, we're able to connect to it.
// Here,
// 1/ we check we have tables, if not, populate the database with tables and set defaults in
// WKX_database_summary and WKX_groups table and
// 2/ if (or once) tables exist, check WKX_database_summary.dbVersion agrees with the INIT class's
// dbVersion(). If not, upgrade WKX_database_summary.dbVersion as necessary
// 3/ populate the config table displaying configuration interface if necessary
// If no admins yet exist, ask for admin configuration to force the input of at least one admin username/password.
	function checkDatabase()
	{
		$newCreate = FALSE;
		$array = $this->db->listTables();
// 1/ (v3.1 requires 36 database tables).
// Some users may have one database shared for several different purposes so check for presence of WKX_config table
		if(!$array || (sizeof($array) == 0) || 
			((array_search('WKX_config', $array) === FALSE) && (array_search('wkx_config', $array) == FALSE)))
		{
			if(!$this->createTables())
				$this->pString .= $this->error->text("dbError", "populateTables");
			$newCreate = TRUE;
		}
// 2/
		if(($this->vars['action'] == 'upgradeDB') && $this->session->getVar('setup_superadmin'))
			$confirm = TRUE;
		else 
			$confirm = FALSE;
		if(!$this->updateDatabase($confirm))
			$this->pString .= $this->error->text("dbError", "updateMySQL");
// 3/
		$this->checkConfigTable();
		if($newCreate)
			$this->update3_6();
	}
// Update the database if required
	function updateDatabase($confirm = FALSE)
	{
		include_once("core/init/INIT.php");
		$recordset = $this->db->select(array('WKX_database_summary'), array("dbVersion"));
		$dbVersion = $this->db->fetchOne($recordset);
// Check added for v3.2.3
		$this->correctNumResources();
		$storedDbVersion = INIT::dbVersion();
		if($dbVersion < $storedDbVersion)
		{
			if(!$confirm)
			{
				$this->confirmUpdateDisplay($dbVersion, $storedDbVersion);
				return FALSE;
			}
			if($dbVersion <= 3.0) // Last solely MySQL version (using ADOdb after this version)
			{
				if(!$fh = fopen("update/updateMySQL.txt", "r"))
					return FALSE;
				if(!$this->addUpdateTables($fh))
					return FALSE;
			}
//			$this->db->escapeString = TRUE;
			$this->db->update('WKX_database_summary', array("dbVersion" => INIT::dbVersion()));
// transfer all paraphrase and quote comments to their own tables for v2.2 upgrade only if those columns exist
// and set default email notification
			if(($dbVersion >= 2) && ($dbVersion <= 2.2))
				$this->updateV2tov22();
// upgrade to v3
			if(($dbVersion >= 2) && ($dbVersion < 3.0))
				$this->updateV3();
// v3.1 moves file attachments into folders based on resource id in attachments/ to allow for multiple attachments per resource.
// Grab file names first then, after adoDB has run, write the new table and rename files.
			if(($dbVersion >= 3.0) && ($dbVersion < 3.1))
				$this->moveFiles1();
// There is a bug in the user bibliography code that sometimes leaves the bibliography field as ",6,5,10,4,3" for example.  Correct it.
			if(($dbVersion >= 2) && ($dbVersion < 3.1))
				$this->correctUserBib();
// Run the new ADOdb createSQL.xml file to ensure we have portable data types.
			$this->db->createMySQL();
// Write hash file attachments to new table
			if(($dbVersion >= 3.0) && ($dbVersion < 3.1))
				$this->moveFiles2();
			if($dbVersion < 3.3)
				$this->correctBs->removeAllSlashes();
			if($dbVersion < 3.4)
				$this->update3_4();
			if($dbVersion < 3.5)
				$this->update3_5();
			if($dbVersion < 3.6)
				$this->update3_6();
			if($dbVersion < 3.8)
				$this->update3_8();
			$this->db->escapeString = FALSE;
			$this->updatedDb = TRUE;
		}
		return TRUE;
	}
// Only the superadmin may update the database
	function confirmUpdateDisplay()
	{
		include_once("core/html/MISC.php");
		include_once("core/html/HTML.php");
		$html = new HTML();
		include_once("core/html/FORM.php");
		include_once("core/html/TABLE.php");
		include_once("core/template/TEMPLATE.php");
		$template = new TEMPLATE('content');
		$template->setVar('heading', $this->message->text("heading", "upgradeDB"));
		if(!$this->session->getVar('setup_superadmin'))
		{
			$pString = MISC::p($this->message->text("config", "upgradeDB1"));
			$recordset = $this->db->select(array('WKX_config'), "contactEmail");
			$email = $this->db->fetchOne($recordset);
			if($email)
				$pString .= MISC::p($this->message->text("config", "upgradeDB2", "&nbsp;($email)"));
			else
				$pString .= MISC::p($this->message->text("config", "upgradeDB2"));
				
			$template->setVar('formStart', FORM::formHeader("upgradeDBLogon"));
			$pString .= MISC::p($this->message->text("authorize", "logonSuperadmin"));
			$pString .= TABLE::tableStart(FALSE, 0, 0, 0, "left", "50%");
			$pString .= TABLE::trStart();
			$pString .= TABLE::td($this->message->text("user", "username") . ":&nbsp;&nbsp;");
			$pString .= TABLE::td(FORM::textInput(FALSE, "username"));
			$pString .= TABLE::trEnd();
			$pString .= TABLE::trStart(FALSE);
			$pString .= TABLE::td($this->message->text("user", "password") . ":&nbsp;&nbsp;");
			$pString .= TABLE::td(FORM::passwordInput(FALSE, "password"));
			$pString .= TABLE::trEnd();
			$pString .= TABLE::trStart();
			$pString .= TABLE::td("&nbsp;");
			$pString .= TABLE::td(FORM::formSubmit(), FALSE, "right");
			$pString .= TABLE::trEnd();
			$pString .= TABLE::tableEnd();
			$template->setVar('formEnd', FORM::formEnd());
			$template->setVar('body', $pString);
			include_once("core/html/CLOSENOMENU.php");
			new CLOSENOMENU($this->db, $template->process());
		}
		else
		{
			$pString = MISC::p($this->message->text("config", "upgradeDB1"));
			$pString .= MISC::p($this->message->text("config", "upgradeDB3"));
			$pString .= FORM::formHeader("upgradeDB");
			$pString .= MISC::p(FORM::formSubmit("upgradeDB"), FALSE, 'right');
			$pString .= FORM::formEnd();
			$template->setVar('body', $pString);
			include_once("core/html/CLOSENOMENU.php");
			new CLOSENOMENU($this->db, $template->process());
		}
	}
// Amend conference_paper resource type
	function update3_8()
	{
		$recordset = $this->db->select(array('WKX_resource'), 
			array(array('WKX_resource.id' => 'resourceId'), 'year1', 'publisher', 'publisherName'), 
			" LEFT JOIN " . $this->db->formatTable('WKX_resource_year') . ' ON ' . 
			$this->db->formatField('WKX_resource.id') . '=' . 
			$this->db->formatField('WKX_resource_year.id') . 
			" LEFT JOIN " . $this->db->formatTable('WKX_resource_misc') . ' ON ' . 
			$this->db->formatField('WKX_resource.id') . '=' . 
			$this->db->formatField('WKX_resource_misc.id') . 	
			" LEFT JOIN " . $this->db->formatTable('WKX_publisher') . ' ON ' . 
			$this->db->formatField('WKX_publisher.id') . '=' . 
			$this->db->formatField('WKX_resource_misc.publisher') . 		
			" WHERE " . $this->db->formatField('type') . '=' . $this->db->tidyInput('conference_paper'));
		while($row = $this->db->loopRecordSet($recordset))
		{
			$this->db->updateSingle('WKX_resource_year', 
				$this->db->formatField('year2') ."=" . $this->db->tidyInput($row['year1']), 
				" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['resourceId']));
			$this->db->updateSingle('WKX_resource_year', 
				$this->db->formatField('year3') ."=" . $this->db->tidyInput($row['year1']), 
				" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['resourceId']));
			$this->db->updateNull('WKX_resource_year', array('year1'), 
				" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['resourceId']));
			$fields = $values = array();
			if($row['publisherName'])
			{
				$fields[] = 'collectionTitle';
				$values[] = $row['publisherName'];
				$this->db->insert('WKX_collection', $fields, $values);
				$id = $this->db->lastAutoId('WKX_collection');
				$this->db->updateSingle('WKX_resource_misc', 
					$this->db->formatField('collection') ."=" . $this->db->tidyInput($id), 
					" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['resourceId']));
				$this->db->updateNull('WKX_resource_misc', array('publisher'), 
					" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['resourceId']));
				$this->db->delete('WKX_publisher', 
					" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['publisher']));
			}
		}
// set the new WKX_users.notifyTimestamp and WKX_users.timestamp to current date
		$this->db->query("UPDATE `WKX_users` set `notifyTimestamp` = NOW(), `timestamp` = NOW()");
	}
// Ensure the new table WKX_cache has a NULL'd row
	function update3_6()
	{
		$resultset = $this->db->select(array('WKX_cache'), '*');
		if(!$this->db->numRows($resultset))
		{
			$this->db->insert('WKX_cache', 'resourceCreators', '');
			$this->db->updateNull('WKX_cache', array('resourceCreators'));
		}
	}
/* A number of changes for v3.5:
1/ Add a bibtexKey for all resources ensuring uniqueness for each key.  The new key follows authorYear[letter].  In rare cases where authorYearz has been used, 
	the key should be authorYear.wikindxId
2/ Collections are more centrally managed.  core/collection/COLLECTIONmap has data mapping for parts of sections indicating which elements are 
common to that collection.  Need to find this info in the <3.5 database, extract it, collate as a base_64-encoded, serialized array and write to 
WKX_collection.collectionString.  collectionTitle and collectionShortTitle are already stored.  In addition, change the collectionType.
For now, we duplicate common information so do not remove redundant data.
*/
	function update3_5()
	{
// Point 1/ above
		include_once("core/file/BIBTEXCONFIG.php");
		$config = new BIBTEXCONFIG();
		$config->bibtex();
		$bibtexKeys = array();
		$letters = range('a', 'z');
		$sizeof = sizeof($letters);
		$recordset = $this->db->select(array('WKX_resource_misc'), 
			array(array('WKX_resource_misc.id' => 'resourceId'), 'creator1', 'creator2', 'year1'), 
			" LEFT JOIN " . $this->db->formatTable('WKX_resource_creator') . ' ON ' . 
			$this->db->formatField('WKX_resource_misc.id') . '=' . 
			$this->db->formatField('WKX_resource_creator.id') . 
			" LEFT JOIN " . $this->db->formatTable('WKX_resource_year') . ' ON ' . 
			$this->db->formatField('WKX_resource_misc.id') . '=' . 
			$this->db->formatField('WKX_resource_year.id'));
		while($row = $this->db->loopRecordSet($recordset))
		{
			$resourceId = $row['resourceId'];
			$year = $row['year1'];
			if(!$row['creator1'] && $row['creator2']) // use editor
				$creatorId = array_shift(split(',', $row['creator2']));
			else
				$creatorId = array_shift(split(',', $row['creator1']));
			$recordset2 = $this->db->select(array('WKX_creator'), array('prefix', 'surname'), 
				' WHERE ' . $this->db->formatField('WKX_creator.id') . '=' . 
				$this->db->tidyInput($creatorId));
			$keyMade = FALSE;
			if(!$this->db->numRows($recordset2)) // anonymous
				$base = 'anon' . $year;
			else
			{
				$creator = $this->db->fetchRow($recordset2);
				$prefix = '';
				if($creator['prefix'])
				{
					$prefix = utf8_decode($creator['prefix']);
					foreach($config->bibtexSpChPlain as $key => $value)
					{
						$char = chr($key);
						$prefix = preg_replace("/$char/", "$value", $prefix);
					}
					$prefix = preg_replace("/\W/", '', $prefix);
				}
				$surname = utf8_decode($creator['surname']);
				foreach($config->bibtexSpChPlain as $key => $value)
				{
					$char = chr($key);
					$surname = preg_replace("/$char/", "$value", $surname);
				}
				$surname = preg_replace("/\W/", '', $surname);
				$base = $prefix . $surname . $year;
			}
			$bibtexKey = $base;
			for($i = 0; $i < $sizeof; $i++)
			{
				if(array_search($bibtexKey, $bibtexKeys) === FALSE)
				{
					$keyMade = TRUE;
					break;
				}
				$bibtexKey = $base . $letters[$i];
			}
			if(!$keyMade)
				$bibtexKey = $base . '.' . $resourceId; // last resort
			$bibtexKeys[$resourceId] = $bibtexKey;
		}
		unset($config);
// 1/ Insert the new bibtexKeys
		foreach($bibtexKeys as $id => $key)
			$this->db->updateSingle('WKX_resource', 
			$this->db->formatField('bibtexKey') ."=" . $this->db->tidyInput($key), 
			" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($id));
// /2 above
		include_once("core/collection/COLLECTIONMAP.php");
		$collection = new COLLECTIONMAP();
		$collection->loadMap();
		$fieldArray = array('field1', 'field2', 'field3', 'field4', 'transTitle', 'transSubtitle', 
			'publisher', 'miscField1', 'miscField2', 'miscField3', 'miscField4', 'miscField5', 'miscField6', 
			'year1', 'year2', 'year3', 'year4', 'creator2', 'creator3', 'creator4', 'creator5');
		$recordset = $this->db->select(array('WKX_resource_misc'), 
			array(array('WKX_resource_misc.id' => 'resourceId'),
			'collection', 'publisher', 'field1', 'field2', 'field3', 'field4', 'transTitle', 'transSubtitle', 
			'publisher', 'miscField1', 'miscField2', 'miscField3', 'miscField4', 'miscField5', 'miscField6', 
			'year1', 'year2', 'year3', 'year4', 'creator2', 'creator3', 'creator4', 'creator5', 'type'), 
			' LEFT JOIN ' . 
				$this->db->formatTable('WKX_resource') . 
				' ON ' . 
				$this->db->formatField('WKX_resource.id') . '=' . 
				$this->db->formatField('WKX_resource_misc.id') . 
			' LEFT JOIN ' . 
				$this->db->formatTable('WKX_resource_year') . 
				' ON ' . 
				$this->db->formatField('WKX_resource_year.id') . '=' . 
				$this->db->formatField('WKX_resource_misc.id') .
			' LEFT JOIN ' . 
				$this->db->formatTable('WKX_resource_creator') . 
				' ON ' . 
				$this->db->formatField('WKX_resource_creator.id') . '=' . 
				$this->db->formatField('WKX_resource_misc.id') .
			' WHERE ' . $this->db->formatField('collection') . ' IS NOT NULL');
		$collections = $resourceIds = array();
		while($row = $this->db->loopRecordSet($recordset))
		{
			$fields = $values = array();
			$id = $row['collection'];
			$resourceType = $collections[$id]['resourceType'] = $row['type'];
			$resourceIds[] = $row['resourceId'];
			$collectionTypes[$row['resourceId']] = $collection->collectionTypes[$resourceType];
			unset($row['collection']);
			unset($row['type']);
			unset($row['resourceId']);
			if(!array_key_exists($id, $collections))
			{
				foreach($row as $key => $value)
				{
					if($value && 
						(
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource']) || 
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource_misc']) || 
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource_year']) || 
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource_creator'])
						)
					)
						$collections[$id][$key] = $value;
				}
			}
// else fill array elements only if empty to get as much data for each collection as possible.
			else
			{
				foreach($fieldArray as $key)
				{
					if($row[$key] && (!array_key_exists($key, $collections[$id]) || 
						!$collections[$id][$key]) && 
						(
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource']) || 
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource_misc']) || 
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource_year']) || 
						array_key_exists($key, 
							$collection->{$collection->collectionTypes[$resourceType]}['resource_creator'])
						)
						)
						$collections[$id][$key] = $row[$key];
				}
			}
		}
		if(!empty($collections))
		{
// Write collections
			foreach($collections as $id => $array)
			{
				$updateArray = array();
				$resourceType = $array['resourceType'];
				unset($array['resourceType']);
				$updateArray['collectionType'] = $collection->collectionTypes[$resourceType];
				if(!empty($array))
					$updateArray['collectionString'] = base64_encode(serialize($array));
				$this->db->update('WKX_collection', $updateArray, 
					" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($id));
			}
// Remove duplicate data from other tables.  No -- we keep this so things like select on publisher works!
/*
			foreach($resourceIds as $id)
			{
				$nullsResource = array_keys($collection->{$collectionTypes[$id]}['resource']);
				$nullsMisc = array_keys($collection->{$collectionTypes[$id]}['resource_misc']);
				$nullsYear = array_keys($collection->{$collectionTypes[$id]}['resource_year']);
				$nullsCreator = array_keys($collection->{$collectionTypes[$id]}['resource_creator']);
				$nullsResource = array('field1', 'field2', 'field3', 'field4', 
					'transTitle', 'transSubtitle');
				$nullsMisc = array('publisher', 'miscField1', 'miscField2', 'miscField3', 'miscField4', 
					'miscField5', 'miscField6');
				$nullsYear = array('year1', 'year2', 'year3', 'year4');
				$nullsCreator = array('creator2', 'creator3', 'creator4', 'creator5');

				if(!empty($nullsResource))
					$this->db->updateNull('WKX_resource', $nullsResource, 
						" WHERE " . $this->db->formatField('id') . 
							"=" . $this->db->tidyInput($id));
				if(!empty($nullsMisc))
					$this->db->updateNull('WKX_resource_misc', $nullsMisc, 
						" WHERE " . $this->db->formatField('id') . 
							"=" . $this->db->tidyInput($id));
				if(!empty($nullsYear))
					$this->db->updateNull('WKX_resource_year', $nullsYear, 
						" WHERE " . $this->db->formatField('id') . 
							"=" . $this->db->tidyInput($id));
				if(!empty($nullsCreator))
					$this->db->updateNull('WKX_resource_creator', $nullsCreator, 
						" WHERE " . $this->db->formatField('id') . 
							"=" . $this->db->tidyInput($id));
			}
// Now, if there are any empty rows in year and resource_creator tables, remove them
			$this->db->delete('WKX_resource_year', ' WHERE ' . 
				$this->db->formatField('year1') . ' IS NULL AND ' . 
				$this->db->formatField('year2') . ' IS NULL AND ' . 
				$this->db->formatField('year3') . ' IS NULL AND ' . 
				$this->db->formatField('year4') . ' IS NULL'); 
			$this->db->optimize("WKX_resource_year");
			$this->db->delete('WKX_resource_creator', ' WHERE ' . 
				$this->db->formatField('creator1') . ' IS NULL AND ' . 
				$this->db->formatField('creator2') . ' IS NULL AND ' . 
				$this->db->formatField('creator3') . ' IS NULL AND ' . 
				$this->db->formatField('creator4') . ' IS NULL AND ' . 
				$this->db->formatField('creator5') . ' IS NULL'); 
			$this->db->optimize("WKX_resource_creator");
*/
		}
	}

// For v3.4, set WKX_resource_timestamp.timestampAdd to the value for timestamp
	function update3_4()
	{
		$resultSet = $this->db->select(array('WKX_resource_timestamp'), array('id', 'timestamp'));
		while($row = $this->db->loopRecordSet($resultSet))
			$this->db->updateSingle('WKX_resource_timestamp', 
			$this->db->formatField('timestampAdd') ."=" . $this->db->tidyInput($row['timestamp']), 
			" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['id']));
//  Somewhere in the past, blank abstract and notes fields have crept in so remove them.  This bug fixed for v3.4.
		$condition = " WHERE " . $this->db->formatField("abstract") . " = ''";
		$this->db->delete("WKX_resource_abstract", $condition);
		$this->db->optimize("WKX_resource_abstract");
		$condition = " WHERE " . $this->db->formatField("text") . " = ''";
		$this->db->delete("WKX_resource_note", $condition);
		$this->db->optimize("WKX_resource_note");
	}
// If a bibtex/endnote import fails due to max execution time being too short (totalResources not written), and the half imported resources are then deleted, 
// the stored totalResources gets out of sync.
	function correctNumResources()
	{
		if($this->session->issetVar("setup_write") || $this->session->issetVar("setup_readOnly"))
			return; // already checked for this session
		$resultSet = $this->db->select(array('WKX_resource'), array('id'));
		$numResources = $this->db->numRows($resultSet);
		$this->db->updateSingle('WKX_database_summary', 
			$this->db->formatField('totalResources') ."=" . $this->db->tidyInput($numResources));
	}
// There is a bug in the user bibliography code that sometimes leaves the bibliography field as ",6,5,10,4,3" for 
// example.  Correct it (< v3.1).
	function correctUserBib()
	{
		$recordSet = $this->db->select(array('WKX_user_bibliography'), array('id', 'bibliography'), 
			" WHERE " . $this->db->formatField('bibliography') . " IS NOT NULL");
		while($row = $this->db->loopRecordSet($recordSet))
		{
			$userBibs = explode(",", $row['bibliography']);
			$newUserBibs = array();
			foreach($userBibs as $bibId)
			{
				if($bibId)
					$newUserBibs[] = $bibId;
			}
			if(!empty($newUserBibs))
			{
				$updateArray = array('bibliography'	=>	join(",", $newUserBibs));
				$this->db->update('WKX_user_bibliography', $updateArray, 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
			}
		}
	}
// Rename attachments by hash and grab file names for use in moveFiles2()   For version 3.1
	function moveFiles1()
	{
		$this->oldFiles = $unlink = $rename = array();
		$fileTypes = array(
							'hqx'		=>	'application/mac-binhex40',
							'mathml'	=>	'application/mathml+xml',
							'doc'		=>	'application/msword',
							'bin'		=>	'application/octet-stream',
							'dms'		=>	'application/octet-stream',
							'lha'		=>	'application/octet-stream',
							'lzh'		=>	'application/octet-stream',
							'exe'		=>	'application/octet-stream',
							'class'		=>	'application/octet-stream',
							'so'		=>	'application/octet-stream',
							'dll'		=>	'application/octet-stream',
							'dmg'		=>	'application/octet-stream',
							'oda'		=>	'application/oda',
							'ogg'		=>	'application/ogg',
							'pdf'		=>	'application/pdf',
							'ai'		=>	'application/postscript',
							'eps'		=>	'application/postscript',
							'ps'		=>	'application/postscript',
							'rdf'		=>	'application/rdf+xml',
							'smi'		=>	'application/smil',
							'smil'		=>	'application/smil',
							'gram'		=>	'application/srgs',
							'grxml'		=>	'application/srgs+xml',
							'mif'		=>	'application/vnd.mif',
							'xls'		=>	'application/vnd.ms-excel',
							'ppt'		=>	'application/vnd.ms-powerpoint',
							'rm'		=>	'application/vnd.rn-realmedia',
							'dcr'		=>	'application/x-director',
							'dir'		=>	'application/x-director',
							'dxr'		=>	'application/x-director',
							'dvi'		=>	'application/x-dvi',
							'spl'		=>	'application/x-futuresplash',
							'gtar'		=>	'application/x-gtar',
							'hdf'		=>	'application/x-hdf',
							'js'		=>	'application/x-javascript',
							'skp'		=>	'application/x-koan',
							'skd'		=>	'application/x-koan',
							'skt'		=>	'application/x-koan',
							'skm'		=>	'application/x-koan',
							'latex'		=>	'application/x-latex',
							'shar'		=>	'application/x-shar',
							'swf'		=>	'application/x-shockwave-flash',
							'sit'		=>	'application/x-stuffit',
							'tar'		=>	'application/x-tar',
							'tcl'		=>	'application/x-tcl',
							'tex'		=>	'application/x-tex',
							'texinfo'	=>	'application/x-texinfo',
							'texi'		=>	'application/x-texinfo',
							't'			=>	'application/x-troff',
							'tr'		=>	'application/x-troff',
							'roff'		=>	'application/x-troff',
							'man'		=>	'application/x-troff-man',
							'me'		=>	'application/x-troff-me',
							'ms'		=>	'application/x-troff-ms',
							'ustar'		=>	'application/x-ustar',
							'xhtml'		=>	'application/xhtml+xml',
							'xht'		=>	'application/xhtml+xml',
							'xslt'		=>	'application/xslt+xml',
							'xml'		=>	'application/xml',
							'xsl'		=>	'application/xml',
							'dtd'		=>	'application/xml-dtd',
							'zip'		=>	'application/zip',
							'au'		=>	'audio/basic',
							'snd'		=>	'audio/basic',
							'mid'		=>	'audio/midi',
							'midi'		=>	'audio/midi',
							'kar'		=>	'audio/midi',
							'mpga'		=>	'audio/mpeg',
							'mp2'		=>	'audio/mpeg',
							'mp3'		=>	'audio/mpeg',
							'aif'		=>	'audio/x-aiff',
							'aiff'		=>	'audio/x-aiff',
							'aifc'		=>	'audio/x-aiff',
							'm3u'		=>	'audio/x-mpegurl',
							'ram'		=>	'audio/x-pn-realaudio',
							'ra'		=>	'audio/x-pn-realaudio',
							'wav'		=>	'audio/x-wav',
							'pdb'		=>	'chemical/x-pdb',
							'xyz'		=>	'chemical/x-xyz',
							'bmp'		=>	'image/bmp',
							'cgm'		=>	'image/cgm',
							'gif'		=>	'image/gif',
							'ief'		=>	'image/ief',
							'jpeg'		=>	'image/jpeg',
							'jpg'		=>	'image/jpeg',
							'jpe'		=>	'image/jpeg',
							'png'		=>	'image/png',
							'svg'		=>	'image/svg+xml',
							'tiff'		=>	'image/tiff',
							'tif'		=>	'image/tiff',
							'djvu'		=>	'image/vnd.djvu',
							'djv'		=>	'image/vnd.djvu',
							'wbmp'		=>	'image/vnd.wap.wbmp',
							'ras'		=>	'image/x-cmu-raster',
							'ico'		=>	'image/x-icon',
							'pnm'		=>	'image/x-portable-anymap',
							'pbm'		=>	'image/x-portable-bitmap',
							'pgm'		=>	'image/x-portable-graymap',
							'ppm'		=>	'image/x-portable-pixmap',
							'rgb'		=>	'image/x-rgb',
							'xbm'		=>	'image/x-xbitmap',
							'xpm'		=>	'image/x-xpixmap',
							'xwd'		=>	'image/x-xwindowdump',
							'vrml'		=>	'model/vrml',
							'wrl'		=>	'model/vrml',
							'css'		=>	'text/css',
							'html'		=>	'text/html',
							'htm'		=>	'text/html',
							'asc'		=>	'text/plain',
							'txt'		=>	'text/plain',
							'rtx'		=>	'text/richtext',
							'rtf'		=>	'text/rtf',
							'sgml'		=>	'text/sgml',
							'sgm'		=>	'text/sgml',
							'tsv'		=>	'text/tab-separated-values',
							'wml'		=>	'text/vnd.wap.wml',
							'wmls'		=>	'text/vnd.wap.wmlscript',
							'etx'		=>	'text/x-setext',
							'mpeg'		=>	'video/mpeg',
							'mpg'		=>	'video/mpeg',
							'mpe'		=>	'video/mpeg',
							'qt'		=>	'video/quicktime',
							'mov'		=>	'video/quicktime',
							'mxu'		=>	'video/vnd.mpegurl',
							'm4u'		=>	'video/vnd.mpegurl',
							'avi'		=>	'video/x-msvideo',
							'movie'		=>	'video/x-sgi-movie',
							'ice'		=>	'x-conference/x-cooltalk',
					);
		$recordSet = $this->db->select(array('WKX_resource'), array('id', 'file'), 
			" WHERE " . $this->db->formatField('file') . " IS NOT NULL");
		while($row = $this->db->loopRecordSet($recordSet))
		{
			$fields = $values = array();
			$file = stripslashes($row['file']);
			if(file_exists("attachments/" . $file))
			{
				$revFileName = strrev($file);
				$fileNameArray = explode(".", $revFileName, 2);
				if((sizeof($fileNameArray) == 2) && array_key_exists(strrev($fileNameArray[0]), $fileTypes))
					$fileType = $fileTypes[strrev($fileNameArray[0])];
				else
					$fileType = 'text/plain';
				$size = filesize("attachments/" . $file);
				$hash = sha1_file("attachments/" . $file);
				$unlink[] = "attachments/" . $file;
				if(!array_key_exists("attachments/" . $file, $rename))
					$rename["attachments/" . $file] = "attachments/" . $hash;
				$this->oldFiles[$row['id']] = array('file' => $file, 'hash' => $hash, 'size' => $size, 
					'fileType' => $fileType);
			}
		}
		foreach($rename as $old => $new)
		{
			if(!file_exists($new))
				rename($old, $new);
		}
		foreach($unlink as $unlinkFile)
		{
			if(file_exists($unlinkFile))
				@unlink($unlinkFile);
		}
	}
// Write new hash files to WKX_attachments.  For version 3.1
	function moveFiles2()
	{
		foreach($this->oldFiles as $id => $array)
		{
			$fields = $values = array();
			$fields[] = 'hashFilename';
			$values[] = $array['hash'];
			$fields[] = 'resourceId';
			$values[] = $id;
			$fields[] = 'filename';
			$values[] = $array['file'];
			$fields[] = 'fileType';
			$values[] = $array['fileType'];
			$fields[] = 'fileSize';
			$values[] = $array['size'];
			$this->db->insert('WKX_attachments', $fields, $values);
		}
	}
// update tables >= v2 <= 2.2
	function updateV2tov22()
	{
// paraphrase comments
		$recordset = $this->db->listFields('WKX_resource_paraphrase_text');
		while($row = $this->db->loopRecordSet($recordset))
		{
			if($row['Field'] == 'comment') // Yes - upgrade
			{
				$recordset2 = $this->db->select(array('WKX_resource_paraphrase_text'), 
					array('id', 'addUserIdParaphrase', 'comment'));
				while($row = $this->db->loopRecordSet($recordset2))
				{
					$fields = $values = array();
					if(!$row['comment'])
						continue;
					$fields[] = 'paraphraseId';
					$values[] = $row['id'];
					$fields[] = 'addUserIdParaphrase';
					$values[] = $row['addUserIdParaphrase'];
					$fields[] = 'comment';
					$values[] = $row['comment'];
					$this->db->insert('WKX_resource_paraphrase_comment', $fields, $values);
				}
//				$this->db->query("ALTER TABLE WKX_resource_paraphrase_text DROP COLUMN comment");
				break;
			}
		}
// quote comments
		$recordset = $this->db->listFields('WKX_resource_quote_text');
		while($row = $this->db->loopRecordSet($recordset))
		{
			if($row['Field'] == 'comment') // Yes - upgrade
			{
				$recordset2 = $this->db->select(array('WKX_resource_quote_text'), 
					array('id', 'addUserIdQuote', 'comment'));
				while($row = $this->db->loopRecordSet($recordset2))
				{
					$fields = $values = array();
					if(!$row['comment'])
						continue;
					$fields[] = 'quoteId';
					$values[] = $row['id'];
					$fields[] = 'addUserIdQuote';
					$values[] = $row['addUserIdQuote'];
					$fields[] = 'comment';
					$values[] = $row['comment'];
					$this->db->insert('WKX_resource_quote_comment', $fields, $values);
				}
//				$this->db->query("ALTER TABLE WKX_resource_quote_text DROP COLUMN comment");
				break;
			}
		}
// email notification
		$recordset = $this->db->select(array('WKX_users'), array("id"));
		while($row = $this->db->loopRecordSet($recordset))
		{
			$recordset2 = $this->db->select(array('WKX_notify'), array("id"), 
				" WHERE" . $this->db->formatField('id') . "=" . $this->db->tidyInput($row['id']));
			if($this->db->numRows($recordset2)) // already in there
				continue;
// Need to add this user to WKX_notify table
			$fields = $values = array();
			$fields[] = 'id';
			$values[] = $row['id'];
			$this->db->insert('WKX_notify', $fields, $values);
		}
// Also, write addUserId to resource_misc, resource_note, resource_abstract tables if not already 
// there - default superadmin id of 1
		$recordset = $this->db->select(array('WKX_resource_misc'), array('id', 'addUserIdResource'), 
			" WHERE " . $this->db->formatField('addUserIdResource') . " IS NULL");
		while($row = $this->db->loopRecordSet($recordset))
			$this->db->update('WKX_resource_misc', array('addUserIdResource' => '1'), 
				" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['id']));
		$recordset = $this->db->select(array('WKX_resource_abstract'), array('id', 'addUserIdAbstract'), 
			" WHERE " . $this->db->formatField('addUserIdAbstract') . " IS NULL");
		while($row = $this->db->loopRecordSet($recordset))
			$this->db->update('WKX_resource_abstract', array('addUserIdAbstract' => '1'), 
			" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['id']));
		$recordset = $this->db->select(array('WKX_resource_note'), array('id', 'addUserIdNote'), 
			" WHERE " . $this->db->formatField('addUserIdNote') . " IS NULL");
		while($row = $this->db->loopRecordSet($recordset))
			$sql = $this->db->update('WKX_resource_note', array('addUserIdNote' => '1'), 
				" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['id']));
	}
// Update to v3 database
	function updateV3()
	{
// Collate WKX_notify and WKX_preferences into WKX_users and drop those 2 tables.
		$recordset = $this->db->select(array('WKX_user_preferences'), 
			array(array('WKX_user_preferences.id' => 'id'), 
			'paging', 'pagingMaxLinks', 'stringLimit', 'language', 'style', 'template', 'notify'), 
			"LEFT JOIN " . $this->db->formatTable("WKX_notify") . " ON " . 
				$this->db->formatField("WKX_notify.id") . "=" . 
				$this->db->formatField("WKX_user_preferences.id"));
		while($row = $this->db->loopRecordSet($recordset))
		{
			$update['paging'] = $row['paging'];
			$update['pagingMaxLinks'] = $row['pagingMaxLinks'];
			$update['stringLimit'] = $row['stringLimit'];
			$update['language'] = $row['language'];
// Change the bibliographic style preference to default APA
			$update['style'] = 'APA';
			$update['template'] = $row['template'];
			$update['notify'] = $row['notify'];
			$this->db->update('WKX_users', $update, 
				" WHERE " . $this->db->formatField('id') . '=' . $this->db->tidyInput($row['id']));
		}
		$this->db->query("DROP TABLE IF EXISTS WKX_notify");
		$this->db->query("DROP TABLE IF EXISTS WKX_user_preferences");
// Change default style to APA in WKX_config
		$this->db->update('WKX_config', array('style' => 'APA'));
// Transfer some fields in WKX_resource to new fields and drop old fields.
// mutually exclusive fields in WKX_resource....
// See docs/resourceDatabaseMatrix.html for the mapping
		include_once("core/resource/RESOURCEMAP.php");
		$map = new RESOURCEMAP();
		$recordset = $this->db->select(array('WKX_resource'), 
			array(array('WKX_resource.id' => 'id'), 'type', 'section', 'thesis',
			'thesislabel', 'seriesTitle', 
			'day', 'month', 'edition', 'seriesNumber', 'numberOfVolumes', 'bookVolumeNumber', 
			'journalVolumeNumber', 'journalissueNumber'), 
			" LEFT JOIN " . $this->db->formatTable("WKX_resource_misc") . " ON " . 
				$this->db->formatField("WKX_resource_misc.id") . "=" . 
				$this->db->formatField("WKX_resource.id"));
		while($row = $this->db->loopRecordSet($recordset))
		{
			if(!array_key_exists('type', $row))  // not sure why this might happen but it occasionally does.
				continue;
			$type = $row['type'];
			$fields = $values = $update = array();
// WKX_resource update
			foreach($map->{$type}['resource'] as $newField => $oldField)
			{
				if(!isset($row[$oldField]) || !$row[$oldField])
					continue;
				$update[$newField] = $row[$oldField];
			}
			if(!empty($update))
				$this->db->update('WKX_resource', $update, 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
// WKX_resource_misc update
			$update = array();
			$fields[] = 'id';
			$values[] = $row['id'];
			$fields[] = 'addUserIdResource';
			$values[] = 1;
			foreach($map->{$type}['resource_misc'] as $newField => $oldField)
			{
				if(!isset($row[$oldField]) || !$row[$oldField])
					continue;
				$update[$newField] = $row[$oldField];
				$fields[] = $newField;
				$values[] = $row[$oldField];
			}
			if(!empty($update))
			{
				$recordset = $this->db->select(array('WKX_resource_misc'), array('id'), " WHERE " . 
					$this->db->formatField('id') . "=" . $this->db->tidyInput($row['id']));
				if($this->db->numRows($recordset))
					$this->db->update('WKX_resource_misc', $update, 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
				else
					$this->db->insert('WKX_resource_misc', $fields, $values);
			}
		}
/*
		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN section");
		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN thesis");
		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN thesisLabel");
		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN medium");
		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN seriesTitle");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN month");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN day");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN edition");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN seriesNumber");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN numberOfVolumes");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN bookVolumeNumber");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN journalVolumeNumber");
		$this->db->query("ALTER TABLE WKX_resource_misc DROP COLUMN journalIssueNumber");
*/
// bookTitle from WKX_resource, is moved to WKX_collection to collectiontitle field
// and id from WKX_collection is updated to 'collection' field in WKX_resource_misc
		$recordset = $this->db->select(array('WKX_resource'), array('id', 'bookTitle'));
		$bookTitleArray = array();
		while($row = $this->db->loopRecordSet($recordset))
		{
			$id = FALSE;
			if(isset($row['bookTitle']) && $row['bookTitle'] && 
				(!$id = array_search($row['bookTitle'], $bookTitleArray)))
			{
				$this->db->insert('WKX_collection', array('collectionTitle', 
					'collectionType'), array($row['bookTitle'], 'book'));
				$id = $this->db->lastAutoId('WKX_collection');
				$bookTitleArray[$id] = $row['bookTitle'];
				$fields = $values = array();
				$fields[] = 'id';
				$values[] = $row['id'];
				$fields[] = 'collection';
				$values[] = $id;
				$fields[] = 'addUserIdResource';
				$values[] = 1; // Force to superadmin as we should have something here.
			}
			if($id)
			{
				$recordset2 = $this->db->select(array('WKX_resource_misc'), array('id'), " WHERE " . 
					$this->db->formatField('id') . "=" . $this->db->tidyInput($row['id']));
				if($this->db->numRows($recordset2))
					$this->db->update('WKX_resource_misc', array('collection' => $id), 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
				else
					$this->db->insert('WKX_resource_misc', $fields, $values);
			}
		}
//		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN bookTitle");
// institution from WKX_resource, is moved to WKX_publisher in publisherName field with publisherType set to institution
// and id from WKX_publisher is updated to 'publisher' field in WKX_resource_misc
		$recordset = $this->db->select(array('WKX_resource'), array('id', 'institution'));
		$institutionArray = array();
		while($row = $this->db->loopRecordSet($recordset))
		{
			$id = FALSE;
			if(isset($row['institution']) && $row['institution'] && 
				(!$id = array_search($row['institution'], $institutionArray)))
			{
				$this->db->insert('WKX_publisher', array('publisherName', 
					'publisherType'), array($row['institution'], 'institution'));
				$id = $this->db->lastAutoId('WKX_publisher');
				$institutionArray[$id] = $row['institution'];
				$fields = $values = array();
				$fields[] = 'id';
				$values[] = $row['id'];
				$fields[] = 'publisher';
				$values[] = $id;
				$fields[] = 'addUserIdResource';
				$values[] = 1;
			}
			if($id)
			{
				$recordset2 = $this->db->select(array('WKX_resource_misc'), array('id'), " WHERE " . 
					$this->db->formatField('id') . "=" . $this->db->tidyInput($row['id']));
				if($this->db->numRows($recordset2))
					$this->db->update('WKX_resource_misc', array('publisher' => $id), 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
				else
					$this->db->insert('WKX_resource_misc', $fields, $values);
			}
		}
//		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN institution");

// conferenceOrganiser and conferenceLocation from WKX_resource, are moved to WKX_publisher in publisherName field 
// and publisherLocation with publisherType set to conference
// and id from WKX_publisher is updated to 'publisher' field in WKX_resource_misc
		$recordset = $this->db->select(array('WKX_resource'), 
			array('id', 'conferenceOrganiser', 'conferenceLocation'));
		$conferenceArray = array();
		while($row = $this->db->loopRecordSet($recordset))
		{
			$id = FALSE;
			if(isset($row['conferenceOrganiser']) && $row['conferenceOrganiser'] && 
				(!$id = array_search($row['conferenceOrganiser'] . ':' . $row['conferenceLocation'],  
					$conferenceArray)))
			{
				$this->db->insert('WKX_publisher', array('publisherName', 'publisherLocation', 
					'publisherType'), array($row['conferenceOrganiser'], $row['conferenceLocation'], 
					'conference'));
				$id = $this->db->lastAutoId('WKX_publisher');
				$conferenceArray[$id] = $row['conferenceOrganiser'] . ":" . $row['conferenceLocation'];
				$fields = $values = array();
				$fields[] = 'id';
				$values[] = $row['id'];
				$fields[] = 'collection';
				$values[] = $id;
				$fields[] = 'addUserIdResource';
				$values[] = 1;
			}
			if($id)
			{
				$recordset2 = $this->db->select(array('WKX_resource_misc'), array('id'), " WHERE " . 
					$this->db->formatField('id') . "=" . $this->db->tidyInput($row['id']));
				if($this->db->numRows($recordset2))
					$this->db->update('WKX_resource_misc', array('publisher' => $id), 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
				else
					$this->db->insert('WKX_resource_misc', $fields, $values);
			}
		}
//		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN conferenceOrganiser");
//		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN conferenceLocation");
//		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN addUserIdResource");
//		$this->db->query("ALTER TABLE WKX_resource DROP COLUMN editUserIdResource");

// In WKX_resource_year, year, thesisYear, thesisAbstractYear, volumeYear and reprintYear have been 
// replaced by year1 ... year3
// mutually exclusive fields in WKX_resource_year....
// See docs/resourceDatabaseMatrix.html for the mapping
		$recordset = $this->db->select(array('WKX_resource_year'), array('id', 'year', 'thesisYear', 
			'thesisAbstractYear', 'reprintYear', 'volumeYear'));
		while($row = $this->db->loopRecordSet($recordset))
		{
			$update = array(); // clear array each loop
			if(isset($row['year']) && $row['year'])
				$update['year1'] = $row['year'];
			if(isset($row['thesisYear']) && $row['thesisYear'])
				$update['year1'] = $row['thesisYear'];
			if(isset($row['thesisAbstractYear']) && $row['thesisAbstractYear'])
				$update['year2'] = $row['thesisAbstractYear'];
			if(isset($row['reprintYear']) && $row['reprintYear'])
				$update['year2'] = $row['reprintYear'];
			if(isset($row['volumeYear']) && $row['volumeYear'])
				$update['year3'] = $row['volumeYear'];
			if(!empty($update))
				$this->db->update('WKX_resource_year', $update, 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
		}
//		$this->db->query("ALTER TABLE WKX_resource_year DROP COLUMN year");
//		$this->db->query("ALTER TABLE WKX_resource_year DROP COLUMN thesisYear");
//		$this->db->query("ALTER TABLE WKX_resource_year DROP COLUMN thesisAbstractYear");
//		$this->db->query("ALTER TABLE WKX_resource_year DROP COLUMN reprintYear");
//		$this->db->query("ALTER TABLE WKX_resource_year DROP COLUMN volumeYear");

// WKX_resource_accessed has been dropped. Day part moves to 'miscField2', month to 'miscField3' and year to 'year2'.
// Need to insert row if row doesn't already exist.
		$recordset = $this->db->select(array('WKX_resource_accessed'), array('id', 'dateAccessed'));
		while($row = $this->db->loopRecordSet($recordset))
		{
			$update = array(); // clear array each loop
			if(!$row['dateAccessed'])
				continue;
			$date = split('-', $row['dateAccessed']);
			$update['miscField2'] = $date[2] + 0;
			$update['miscField3'] = $date[1] + 0;
			$year = $date[0];
			$recordset2 = $this->db->select(array('WKX_resource_misc'), array('id'), " WHERE " . 
				$this->db->formatField('id') . "=" . $this->db->tidyInput($row['id']));
			if($this->db->numRows($recordset))
				$this->db->update('WKX_resource_misc', $update, 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
			else
				$this->db->insert('WKX_resource_misc', array('id', 'miscField2', 'miscField3', 
					'addUserIdResource'), array($row['id'], 
					$update['day'], $update['month'], '1'));
			$recordset2 = $this->db->select(array('WKX_resource_year'), array('id'), " WHERE " . 
				$this->db->formatField('id') . "=" . $this->db->tidyInput($row['id']));
			if($this->db->numRows($recordset2))
				$this->db->update('WKX_resource_year', array('year2' => $year), 
					" WHERE " . $this->db->formatField('id') . '=' . 
					$this->db->tidyInput($row['id']));
			else
				$this->db->insert('WKX_resource_year', array('id', 'year2'), 
					array($row['id'], $year));
		}
		$this->db->query("DROP TABLE IF EXISTS WKX_resource_accessed");
	}
// No tables in fresh database so create them
	function createTables()
	{
		$this->db->createMySQL();
		$this->populateTables();
		return TRUE;
// get SQL code from createMySQL.txt
		if(!$fh = fopen("update/createMySQL.txt", "r"))
		{
			$this->pString .= $this->error->text("dbError", "fileOpen");
			return FALSE;
		}
		$this->addUpdateTables($fh);
		$this->populateTables();
		return TRUE;
	}
// Concatenate file handle's contents into long string tossing out commented lines and run DB query
	function addUpdateTables($fh)
	{
		$fileContents = '';
		while(!feof($fh))
		{
			$line = fgets($fh);
			if(!preg_match("/^#/", $line))
				$fileContents .= $line;
		}
		fclose($fh);
		if(!$fileContents)
			return FALSE;
		$sqlArray = explode(";", $fileContents);
// for some reason last element in $sqlArray is always empty - remove it so it doesn't
// mess up the db query.
		array_pop($sqlArray);
		foreach($sqlArray as $sql)
		{
			$sql = trim($sql) . ";";
// NB - we don't check query executes so that we can have rolling updates in updateMySQL.txt that span several dbVersions.
// i.e. any ALTER TABLE statements that produce an error (because they've already been updated) don't cause failure here.
			$this->db->queryNoError($sql);
		}
		return TRUE;
	}
// Intercept for initial configuration of database by admin and, if
// necessary, display admin configuration interface.
	function checkConfigTable()
	{
		if(!$this->rowExists())
		{
			include_once("core/admin/CONFIG.php");
			$config = new CONFIG($this->db);
			if(isset($this->vars["action"]) && $this->vars['action'] == 'adminConfigure')
				$this->pString .= $config->write($this->vars);
			else
			{
// write preliminary stringLimit, write and superadmin to session and display configuration screen
				$this->session->setVar("setup_stringLimit", 40);
				$this->session->setVar("setup_write", TRUE);
				$this->session->setVar("setup_superadmin", TRUE);
// superadmin userId is always 1
				$this->session->setVar("setup_userId", 1);
				include_once("core/html/MISC.php");
				$this->pString .= $config->displaySetup(MISC::p($this->message->text("config", 
					"start"), "error", "center"));
			}
		}
	}
// At first initialization of wikindx3 database, populate the summary table and category table
	function populateTables()
	{
		include_once("core/init/INIT.php");
		$fields = array('totalResources', 'totalQuotes', 'totalParaphrases', 'totalMusings', 'dbVersion');
		$values = array('0', '0', '0', '0', INIT::dbVersion());
		$this->db->insert('WKX_database_summary', $fields, $values);
		$this->db->insert('WKX_category', array('category'), array('General'));
	}
// Check if the WKX_config table has been initialized.  Row must be returned as evidence of prior configuration.
	function rowExists()
	{
		$recordset = $this->db->select(array('WKX_config'), array("title", "contactEmail", "description", 
			"fileDeleteSeconds", "paging", "pagingMaxLinks", "stringLimit", "language", "style", 
			"template", "multiUser", "userRegistration", "notify", "imgWidthLimit", "imgHeightLimit", 
			"fileAttach", "fileViewLoggedOnOnly", "maxPaste", "lastChanges", "pagingTagCloud", "importBib", 
			"lastChangesType", "emailNews", "lastChangesDayLimit"));
		if(!$this->row = $this->db->fetchRow($recordset))
			return FALSE;
		return TRUE;
	}
// If this is the first time, populate the session with some default variables.
	function populateSession()
	{
		if($this->session->issetVar("setup_write") || $this->session->issetVar("setup_readOnly"))
// Already initialized
			return;
// If WKX_config table has been setup, pull some values (those used frequently) from it and store in session
		if(isset($this->row) && $this->row)
		{
			if(!$this->writeSession($this->row))
				$this->pString .= $this->error->text("sessionError", "write");
		}
	}
// Write the basic session
	function writeSession($array, $session = FALSE)
	{
		include_once("core/styles/LOADSTYLE.php");
		if($session)
			$this->session = $session;
		if(!$this->session->setVar("setup_language", $array['language']))
			return FALSE;
// Check requested style plug-in has not been deleted.  If so, return first in list so that something is safely 
// displayed when listing bibliographies.
		$styles = LOADSTYLE::loadDir("styles/bibliography");
		if(!array_key_exists($array['style'], $styles))
		{
			$styleKeys = array_keys($styles);
			$array['style'] = array_shift($styleKeys);
		}
		if(!$this->session->setVar("setup_style", $array['style']))
			return FALSE;
		if(!$this->session->setVar("setup_title", $array['title']))
			return FALSE;
		if(!$this->session->setVar("setup_template", $array['template']))
			return FALSE;
		if(!$this->session->setVar("setup_fileDeleteSeconds", $array['fileDeleteSeconds']))
			return FALSE;
		if(!$this->session->setVar("setup_paging", $array['paging']))
			return FALSE;
		if(!$this->session->setVar("setup_pagingMaxLinks", $array['pagingMaxLinks']))
			return FALSE;
		if(array_key_exists('pagingTagCloud', $array) && 
		!$this->session->setVar("setup_pagingTagCloud", $array['pagingTagCloud']))
			return FALSE;
		if(!$this->session->setVar("setup_stringLimit", $array['stringLimit']))
			return FALSE;
		if(!$this->session->setVar("setup_maxPaste", $array['maxPaste']))
			return FALSE;
		if(!$this->session->setVar("setup_lastChanges", $array['lastChanges']))
			return FALSE;
		if(!$this->session->setVar("setup_lastChangesType", $array['lastChangesType']))
			return FALSE;
		if(!$this->session->setVar("setup_lastChangesDayLimit", $array['lastChangesDayLimit']))
			return FALSE;
// Allow multi-user operation?
		if($array['multiUser'] == 'Y')
		{
			if(!$this->session->setVar("setup_multiUser", TRUE))
				return FALSE;
		}
		if($array['userRegistration'] == 'Y')
		{
			if(!$this->session->setVar("setup_userRegistration", TRUE))
				return FALSE;
		}
// allow email notification?
		if($array['notify'] == 'Y')
		{
			if(!$this->session->setVar("setup_notify", TRUE))
				return FALSE;
		}
// allow file attachments?
		if($array['fileAttach'] == 'Y')
		{
			if(!$this->session->setVar("setup_fileAttach", TRUE))
				return FALSE;
		}
// allow only logged on users to view file attachments?
		if($array['fileViewLoggedOnOnly'] == 'Y')
		{
			if(!$this->session->setVar("setup_fileViewLoggedOnOnly", TRUE))
				return FALSE;
		}
// Allow users with write access to import bibliographies?
		if($array['importBib'] == 'Y')
		{
			if(!$this->session->setVar("setup_importBib", TRUE))
				return FALSE;
		}
// Email news items ot registered users
		if($array['emailNews'] == 'Y')
		{
			if(!$this->session->setVar("setup_emailNews", TRUE))
				return FALSE;
		}
// set setup_bibliographies to TRUE if there exist populated user bibliographies (used in MENU.php)
		$recordset = $this->db->select(array('WKX_user_bibliography'), array('id'), 
			" WHERE " . $this->db->formatField('bibliography') . ' IS NOT NULL');
		if($this->db->numRows($recordset))
		{
			if(!$this->session->setVar("setup_bibliographies", TRUE))
				return FALSE;
		}
// set setup_news to TRUE if there exist news items (used in MENU.php)
		$recordset = $this->db->select(array('WKX_news'), array('id'), 
			" WHERE " . $this->db->formatField('news') . ' IS NOT NULL');
		if($this->db->numRows($recordset))
		{
			if(!$this->session->setVar("setup_news", TRUE))
				return FALSE;
		}
		return TRUE;
	}
}
?>
